package testCase;

import Game.EventExecution;
import Game.Game;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import java.util.StringTokenizer;
import java.util.Vector;

import org.junit.Test;

import junit.framework.TestCase;
import Card.*;
import GameElement.*;
import PlayerElement.*;
import org.junit.After;
import org.junit.Before;

public class TestGameOptionMenu extends TestCase{
	
	private final ByteArrayOutputStream output = new ByteArrayOutputStream();
	 
	@Before
	public void setUp() {
		System.setOut(new PrintStream(this.output));
	}
	 
	@After
	public void tearDown() {
		System.setOut(null);
	}
	
	@Test
	public void testSelectOption1_ActCard_Accept_InteractionScore() throws Exception{
		String data = "2\nAustin\n1\nPeter\n2\n1\nA";
		System.setIn(new ByteArrayInputStream(data.getBytes()));
		Game game = new Game("testActCard.txt");
		Vector gamePlayer_Vector = new Vector();
		gamePlayer_Vector = game.getPlayerQueue();
		GamePlayer gamePlayer = (GamePlayer) gamePlayer_Vector.get(0);
		game.optionsMenu(1);
		int excepted = 60;
		assertEquals(excepted, gamePlayer.getInteractionScore());
	}
	
	@Test
	public void testSelectOption1_ActCard_Accept_Score() throws Exception{
		String data = "2\nAustin\n1\nPeter\n2\n1\nA";
		System.setIn(new ByteArrayInputStream(data.getBytes()));
		Game game = new Game("testActCard.txt");
		Vector gamePlayer_Vector = new Vector();
		gamePlayer_Vector = game.getPlayerQueue();
		GamePlayer gamePlayer = (GamePlayer) gamePlayer_Vector.get(0);
		game.optionsMenu(1);
		int excepted = 300 + 100;
		assertEquals(excepted, gamePlayer.getScore());
	}
	
	@Test
	public void testSelectOption1_ActCard_Reject_Score() throws Exception{
		String data = "2\nAustin\n2\nPeter\n2\n1\nR";
		System.setIn(new ByteArrayInputStream(data.getBytes()));
		Game game = new Game("testActCard.txt");
		Vector gamePlayer_Vector = new Vector();
		gamePlayer_Vector = game.getPlayerQueue();
		GamePlayer gamePlayer = (GamePlayer) gamePlayer_Vector.get(0);
		game.optionsMenu(1);		
		int excepted = 300 - 100;
		assertEquals(excepted, gamePlayer.getScore());
	}
	
	@Test
	public void testSelectOption1_ActCard_InvalidInput() throws Exception{
		String data = "2\nAustin\n3\nPeter\n2\n1\nH\nR";
		System.setIn(new ByteArrayInputStream(data.getBytes()));
		Game game = new Game("testActCard.txt");
		Vector gamePlayer_Vector = new Vector();
		gamePlayer_Vector = game.getPlayerQueue();
		GamePlayer gamePlayer = (GamePlayer) gamePlayer_Vector.get(0);
		game.optionsMenu(1);		
		int excepted = 100 - 100;
		assertEquals(excepted, gamePlayer.getScore());
	}
	
	@Test
	public void testSelectOption1_SayCard_Accept_CommunicationScore() throws Exception{
		String data = "2\nAustin\n4\nPeter\n2\n1\nA\nY";
		System.setIn(new ByteArrayInputStream(data.getBytes()));
		Game game = new Game("testSayCard.txt");
		Vector gamePlayer_Vector = new Vector();
		gamePlayer_Vector = game.getPlayerQueue();
		GamePlayer gamePlayer = (GamePlayer) gamePlayer_Vector.get(0);
		game.optionsMenu(1);
		int excepted = 60;
		assertEquals(excepted, gamePlayer.getCommunicationScore());
	}
	
	@Test
	public void testSelectOption1_SayCard_Accept_Score() throws Exception{
		String data = "2\nAustin\n4\nPeter\n2\n1\nA\nY";
		System.setIn(new ByteArrayInputStream(data.getBytes()));
		Game game = new Game("testSayCard.txt");
		Vector gamePlayer_Vector = new Vector();
		gamePlayer_Vector = game.getPlayerQueue();
		GamePlayer gamePlayer = (GamePlayer) gamePlayer_Vector.get(0);
		game.optionsMenu(1);
		int excepted = 100 + 50;
		assertEquals(excepted, gamePlayer.getScore());
	}
	
	@Test
	public void testSelectOption1_SayCard_Accept_Player_haveFeedback() throws Exception{
		String data = "2\nAustin\n1\nPeter\n5\n1\nA\nY";
		System.setIn(new ByteArrayInputStream(data.getBytes()));
		Game game = new Game("testSayCard.txt");
		Vector gamePlayer_Vector = new Vector();
		gamePlayer_Vector = game.getPlayerQueue();
		GamePlayer gamePlayer = (GamePlayer) gamePlayer_Vector.get(1);
		game.optionsMenu(1);
		int excepted = 200 + 25;
		assertEquals(excepted, gamePlayer.getScore());
	}
	
	@Test
	public void testSelectOption1_SayCard_Accept_Player_noFeedback() throws Exception{
		String data = "2\nAustin\n1\nPeter\n6\n1\nA\nN";
		System.setIn(new ByteArrayInputStream(data.getBytes()));
		Game game = new Game("testSayCard.txt");
		Vector gamePlayer_Vector = new Vector();
		gamePlayer_Vector = game.getPlayerQueue();
		GamePlayer gamePlayer = (GamePlayer) gamePlayer_Vector.get(1);
		game.optionsMenu(1);
		int excepted = 200 - 25;
		assertEquals(excepted, gamePlayer.getScore());
	}
	
	@Test
	public void testSelectOption1_SayCard_Reject_Score() throws Exception{
		String data = "2\nAustin\n1\nPeter\n2\n1\nR\nY";
		System.setIn(new ByteArrayInputStream(data.getBytes()));
		Game game = new Game("testSayCard.txt");
		Vector gamePlayer_Vector = new Vector();
		gamePlayer_Vector = game.getPlayerQueue();
		GamePlayer gamePlayer = (GamePlayer) gamePlayer_Vector.get(0);
		game.optionsMenu(1);
		int excepted = 300 - 50;
		assertEquals(excepted, gamePlayer.getScore());
	}
	
	@Test
	public void testSelectOption1_SayCard_Invalid() throws Exception{
		String data = "2\nAustin\n1\nPeter\n2\n1\nW\nA\nY";
		System.setIn(new ByteArrayInputStream(data.getBytes()));
		Game game = new Game("testSayCard.txt");
		Vector gamePlayer_Vector = new Vector();
		gamePlayer_Vector = game.getPlayerQueue();
		GamePlayer gamePlayer = (GamePlayer) gamePlayer_Vector.get(0);
		game.optionsMenu(1);
		int excepted = 300 + 50;
		assertEquals(excepted, gamePlayer.getScore());
	}
	
	@Test
	public void testSelectOption1_EventCard_Answer1_UnderstandingScore() throws Exception{
		String data = "2\nAustin\n1\nPeter\n2\n1\n1";
		System.setIn(new ByteArrayInputStream(data.getBytes()));
		Game game = new Game("testEventCard.txt");
		Vector gamePlayer_Vector = new Vector();
		gamePlayer_Vector = game.getPlayerQueue();
		GamePlayer gamePlayer = (GamePlayer) gamePlayer_Vector.get(0);
		game.optionsMenu(1);
		int excepted = 60;
		assertEquals(excepted, gamePlayer.getUnderstandingScore());
	}
	
	@Test
	public void testSelectOption1_EventCard_Answer1_Score() throws Exception{
		String data = "2\nAustin\n1\nPeter\n2\n1\n1";
		System.setIn(new ByteArrayInputStream(data.getBytes()));
		Game game = new Game("testEventCard.txt");
		Vector gamePlayer_Vector = new Vector();
		gamePlayer_Vector = game.getPlayerQueue();
		GamePlayer gamePlayer = (GamePlayer) gamePlayer_Vector.get(0);
		game.optionsMenu(1);
		int excepted = 300 + 100;
		assertEquals(excepted, gamePlayer.getScore());
	}
	
	@Test
	public void testSelectOption1_EventCard_Answer2_UnderstandingScore() throws Exception{
		String data = "2\nAustin\n1\nPeter\n2\n1\n2";
		System.setIn(new ByteArrayInputStream(data.getBytes()));
		Game game = new Game("testEventCard.txt");
		Vector gamePlayer_Vector = new Vector();
		gamePlayer_Vector = game.getPlayerQueue();
		GamePlayer gamePlayer = (GamePlayer) gamePlayer_Vector.get(0);
		game.optionsMenu(1);
		int excepted = 60;
		assertEquals(excepted, gamePlayer.getUnderstandingScore());
	}
	
	@Test
	public void testSelectOption1_EventCard_Answer2_Score() throws Exception{
		String data = "2\nAustin\n1\nPeter\n2\n1\n2";
		System.setIn(new ByteArrayInputStream(data.getBytes()));
		Game game = new Game("testEventCard.txt");
		Vector gamePlayer_Vector = new Vector();
		gamePlayer_Vector = game.getPlayerQueue();
		GamePlayer gamePlayer = (GamePlayer) gamePlayer_Vector.get(0);
		game.optionsMenu(1);
		int excepted = 300 + 150;
		assertEquals(excepted, gamePlayer.getScore());
	}
	
	@Test
	public void testSelectOption1_EventCard_BadAnswer_UnderstandingScore() throws Exception{
		String data = "2\nAustin\n1\nPeter\n2\n1\n4";
		System.setIn(new ByteArrayInputStream(data.getBytes()));
		Game game = new Game("testEventCard.txt");
		Vector gamePlayer_Vector = new Vector();
		gamePlayer_Vector = game.getPlayerQueue();
		GamePlayer gamePlayer = (GamePlayer) gamePlayer_Vector.get(0);
		game.optionsMenu(1);
		int excepted = 40;
		assertEquals(excepted, gamePlayer.getUnderstandingScore());
	}
	
	@Test
	public void testSelectOption1_EventCard_BadAnswer_Score() throws Exception{
		String data = "2\nAustin\n1\nPeter\n2\n1\n4";
		System.setIn(new ByteArrayInputStream(data.getBytes()));
		Game game = new Game("testEventCard.txt");
		Vector gamePlayer_Vector = new Vector();
		gamePlayer_Vector = game.getPlayerQueue();
		GamePlayer gamePlayer = (GamePlayer) gamePlayer_Vector.get(0);
		game.optionsMenu(1);
		int excepted = 300 - 50;
		assertEquals(excepted, gamePlayer.getScore());
	}
	
	@Test
	public void testSelectOption2_Player_endTurn() throws Exception{
		String data = "2\nAustin\n1\nPeter\n2\n2\nA";
		System.setIn(new ByteArrayInputStream(data.getBytes()));
		Game game = new Game("testActCard.txt");
		Vector gamePlayer_Vector = new Vector();
		gamePlayer_Vector = game.getPlayerQueue();
		GamePlayer gamePlayer = (GamePlayer) gamePlayer_Vector.get(0);
		game.optionsMenu(1);
		int excepted = 300 - 50;
		assertEquals(excepted, gamePlayer.getScore());
	}
	
	@Test
	public void test_isGameEnd_PlayerA_1000score() throws Exception{
		String data = "2\nAustin\n1\nPeter\n2\n1\nA";
		System.setIn(new ByteArrayInputStream(data.getBytes()));
		Game game = new Game("testActCard.txt");
		Vector gamePlayer_Vector = new Vector();
		gamePlayer_Vector = game.getPlayerQueue();
		GamePlayer gamePlayer = (GamePlayer) gamePlayer_Vector.get(0);
		gamePlayer.modifyScore(700);
		game.optionsMenu(1);
		int excepted = 1100;
		//boolean excepted = true;
		assertEquals(excepted, gamePlayer.getScore());
	}
	
	@Test
	public void test_isGameEnd_PlayerAB_win() throws Exception{
		String data = "2\nAustin\n1\nPeter\n2\n1\nA";
		System.setIn(new ByteArrayInputStream(data.getBytes()));
		Game game = new Game("testActCard.txt");
		Vector gamePlayer_Vector = new Vector();
		gamePlayer_Vector = game.getPlayerQueue();
		GamePlayer gamePlayerA = (GamePlayer) gamePlayer_Vector.get(0);
		GamePlayer gamePlayerB = (GamePlayer) gamePlayer_Vector.get(1);
		gamePlayerA.modifyScore(700);
		gamePlayerB.modifyScore(800);
		game.optionsMenu(1);
		String excepted = "Congratulation, you won!";
		int actualString = output.toString().lastIndexOf(excepted);
		boolean actual = actualString >= 0;
		assertEquals(true, actual);
	}
	
	@Test
	public void test_isGameEnd_PlayerAB_lose() throws Exception{
		String data = "2\nAustin\n1\nPeter\n2\n1\nR";
		System.setIn(new ByteArrayInputStream(data.getBytes()));
		Game game = new Game("testActCard.txt");
		Vector gamePlayer_Vector = new Vector();
		gamePlayer_Vector = game.getPlayerQueue();
		GamePlayer gamePlayerA = (GamePlayer) gamePlayer_Vector.get(0);
		GamePlayer gamePlayerB = (GamePlayer) gamePlayer_Vector.get(1);
		gamePlayerA.modifyScore(-250);
		gamePlayerB.modifyScore(-10);
		game.optionsMenu(1);
		String excepted = "Game over, you lost!";
		int actualString = output.toString().lastIndexOf(excepted);
		boolean actual = actualString >= 0;
		assertEquals(true, actual);
	}
}
